package ldh.fx.adminfx.help;

import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle;
import javafx.stage.Popup;
import javafx.stage.Window;

public class MovableHelper {

    public static void movable(Region movablePane) {
        if (movablePane == null) return;
        MovableListener movableListener = new MovableListener(movablePane);
        movablePane.setOnMouseDragged(e->movableListener.moveWindow(e));
        movablePane.setOnMouseReleased(e->movableListener.endMoveWindow(e));
        movablePane.setOnDragDetected(e->movableListener.startMoveWindow(e));
    }

    static class MovableListener {
        private Region movablePane;

        private Rectangle moveTrackingRect;
        private Popup moveTrackingPopup;

        private double startMoveX = -1;
        private double startMoveY = -1;
        private Boolean dragging = false;

        public MovableListener(Region movablePane) {
            this.movablePane = movablePane;
        }

        public void startMoveWindow(MouseEvent evt) {
            Scene scene = movablePane.getScene();
//            if(scene.getCursor() != Cursor.DEFAULT) return;
            if (evt.getX() < 3 || evt.getX() > movablePane.getScene().getWindow().getWidth() - 3
                    || evt.getY() > movablePane.getScene().getWindow().getHeight() - 3) return;
            startMoveX = evt.getScreenX();
            startMoveY = evt.getScreenY();
            dragging = true;

            moveTrackingRect = new Rectangle();
            moveTrackingRect.setWidth(movablePane.getScene().getWindow().getWidth());
            moveTrackingRect.setHeight(movablePane.getScene().getWindow().getHeight());
            moveTrackingRect.setStyle("-fx-fill: #f3f3f4;\n" +
                    "    -fx-arc-height: 4;\n" +
                    "    -fx-arc-width: 4;" +
                    "-fx-opacity: 0.6");

            moveTrackingPopup = new Popup();
            moveTrackingPopup.getContent().add(moveTrackingRect);
            moveTrackingPopup.show(movablePane.getScene().getWindow());
            moveTrackingPopup.setOnHidden( (e) -> resetMoveOperation());
        }

        public void moveWindow(MouseEvent evt) {
            if (dragging) {
                double endMoveX = evt.getScreenX();
                double endMoveY = evt.getScreenY();
                Window w = movablePane.getScene().getWindow();
                double stageX = w.getX();
                double stageY = w.getY();
                moveTrackingPopup.setX(stageX + (endMoveX - startMoveX));
                moveTrackingPopup.setY(stageY + (endMoveY - startMoveY));
            }
        }

        public void endMoveWindow(MouseEvent evt) {
            if (dragging) {
                double endMoveX = evt.getScreenX();
                double endMoveY = evt.getScreenY();
                Window w = movablePane.getScene().getWindow();
                double stageX = w.getX();
                double stageY = w.getY();
                w.setX(stageX + (endMoveX - startMoveX));
                w.setY(stageY + (endMoveY - startMoveY));
                if (moveTrackingPopup != null) {
                    moveTrackingPopup.hide();
                    moveTrackingPopup = null;
                }
            }
            resetMoveOperation();
        }

        private void resetMoveOperation() {
            startMoveX = 0;
            startMoveY = 0;
            dragging = false;
            moveTrackingRect = null;
        }
    }


}
